package org.xxforest.game.notsing.roles;

import org.xxforest.game.core.XX;
import org.xxforest.game.core.scenes.scene2d.XXNode;
import org.xxforest.game.core.scenes.scene2d.XXTouchable;
import org.xxforest.game.core.scenes.scene2d.ui.XXImage;
import org.xxforest.game.core.tween.XXNodeAccessor;
import org.xxforest.game.core.tween.XXTween;
import org.xxforest.game.core.tween.XXTweenCallBack;
import org.xxforest.game.core.utils.XXPoint;
import org.xxforest.game.notsing.common.Action;
import org.xxforest.game.notsing.common.Dir;

import aurelienribon.tweenengine.equations.Linear;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;

public class Spirit extends XXNode{
	
	/**	精灵所有帧[动作][方向][帧]*/
	private TextureRegion[][][] frames ;
	/**	纹理集合[动作]*/
	private TextureRegion[] textureRegion ;
	
	/**	当前动作*/
	private Action action ;
	/**	当前方向*/
	private Dir dir ;
	/**	当前帧*/
	private int curFrameIndex ;
	/**	当前帧图片*/
	private XXImage curFrameImage ;
	/**	移动动画*/
	private XXTween moveTween ;
	/**	移动速度*/
	private float moveSpeed ;

	public Spirit(String waitTextureImage , String runTextureImage , String attactTextureImage) {
		frames = new TextureRegion[Action.length()][][] ;
		textureRegion = new TextureRegion[Action.length()];
		textureRegion[Action.wait.ordinal()] = new TextureRegion(new Texture(Gdx.files.internal(waitTextureImage)));
		textureRegion[Action.run.ordinal()] = new TextureRegion(new Texture(Gdx.files.internal(runTextureImage)));
		textureRegion[Action.attack.ordinal()] = new TextureRegion(new Texture(Gdx.files.internal(attactTextureImage)));
		dir = Dir.down ;
		action = Action.wait ;
	}

	public static Spirit create(String waitTextureImage , String runTextureImage , String attactTextureImage){
		return new Spirit(waitTextureImage,runTextureImage,attactTextureImage) ;
	}
	
	@Override
	public void onCreate() {
		moveSpeed = 300f ;
		//切割图片
		frames[Action.wait.ordinal()] = textureRegion[Action.wait.ordinal()].split(256, 256) ;
		frames[Action.run.ordinal()] = textureRegion[Action.run.ordinal()].split(256, 256) ;
		frames[Action.attack.ordinal()] = textureRegion[Action.attack.ordinal()].split(256, 256) ;
		
		curFrameImage = XXImage.create(getFrame()) ;
		curFrameImage.setTouchable(XXTouchable.disabled);
		this.setTouchable(XXTouchable.disabled) ;
		this.add(curFrameImage);
	}
	
	/**
	 * 改变动作
	 * @param action
	 */
	public void changeAction(Action action){
		this.action = action ;
		curFrameImage.setTextureRegion(getFrame()) ;
		resetSize();
	}
	
	/**
	 * 重置大小
	 */
	private void resetSize() {
		setSize(curFrameImage.getWidth(), curFrameImage.getHeight());
		setAnchorPoint(curFrameImage.getWidth()/2, curFrameImage.getHeight()/2);
	}

	/**
	 * 改变方向
	 * @param dir
	 */
	public void changeDir(Dir dir){
		this.dir = dir ;
		curFrameImage.setTextureRegion(getFrame()) ;
		resetSize();
	}
	
	/**
	 * 下一帧
	 */
	public void nextFrame(){
		curFrameIndex ++ ;
		curFrameImage.setTextureRegion(getFrame()) ;
		resetSize();
	}

	/**
	 * 获取当前帧
	 * @return
	 */
	public TextureRegion getFrame() {
		if(curFrameIndex >= frames[action.ordinal()][dir.ordinal()].length){
			curFrameIndex = 0 ;
			actionFrameCompleteEvent();
		}
		return frames[action.ordinal()][dir.ordinal()][curFrameIndex];
	}

	/**
	 * 动作帧完成事件
	 */
	private void actionFrameCompleteEvent() {
		if(action == Action.attack){
			changeAction(Action.wait);
		}
	}

	@Override
	public void draw(SpriteBatch batch, float delta) {
	}

	public void resetFrameIndex() {
		curFrameIndex = 0 ;
	}

	public void gotoPoint(XXPoint toPoint) {
		
		XXPoint point = getPoint();
		if(toPoint.equals(point) || action == Action.attack){
			return ;
		}
		
		float degree = XXPoint.xxpToDegree(toPoint.copy().reduce(point));
		Dir byDegree = Dir.getByDegree(degree);
		this.changeDir(byDegree);
		this.changeAction(Action.run);
		float distance = XXPoint.xxpDistance(point, toPoint);
		
		if(moveTween != null){
			moveTween.free() ;
		}
		
		moveTween = XXTween.to(this, XXNodeAccessor.POS_XY , distance / moveSpeed)
				.ease(Linear.INOUT).target(toPoint.x,toPoint.y).setCompleteCallBack(new XXTweenCallBack() {
					
					@Override
					public void doEvent(Object target, XXTween tween) {
						stopMove();
					}
				});
		
		this.addTween(moveTween);
	}
	
	public void stopMove(){
		this.moveTween.free() ;
		if(action != Action.attack){
			changeAction(Action.wait);
		}
	}

	public void attack() {
		if(action != Action.attack){
			if(this.moveTween != null){
				this.moveTween.free() ;
			}
			this.resetFrameIndex();
			this.changeAction(Action.attack);
		}
	}

	@Override
	public void setPosition(float x, float y) {
		super.setPosition(x, y);
		XX.director.getCamera().position.set(x, y, 0);
	}

	
}
